package com.dh.leetcode.k1;

import org.junit.Assert;
import org.junit.Test;

/**
 * @ClassName: _1052_grumpy_bookstore_owner
 * @Description: 1052. 爱生气的书店老板
 * 今天，书店老板有一家店打算试营业 customers.length 分钟。每分钟都有一些顾客（customers[i]）会进入书店，
 * 所有这些顾客都会在那一分钟结束后离开。
 * <p>
 * 在某些时候，书店老板会生气。 如果书店老板在第 i 分钟生气，那么 grumpy[i] = 1，否则 grumpy[i] = 0。 当书店老板生气时
 * ，那一分钟的顾客就会不满意，不生气则他们是满意的。
 * <p>
 * 书店老板知道一个秘密技巧，能抑制自己的情绪，可以让自己连续 X 分钟不生气，但却只能使用一次。
 * <p>
 * 请你返回这一天营业下来，最多有多少客户能够感到满意的数量。
 * <p>
 * <p>
 * 示例：
 * <p>
 * 输入：customers = [1,0,1,2,1,1,7,5], grumpy = [0,1,0,1,0,1,0,1], X = 3
 * 输出：16
 * 解释：
 * 书店老板在最后 3 分钟保持冷静。
 * 感到满意的最大客户数量 = 1 + 1 + 1 + 1 + 7 + 5 = 16.
 * <p>
 * https://leetcode-cn.com/problems/grumpy-bookstore-owner/
 * @Author: shouzimu
 * @Date: 2021/2/23 11:00
 */
public class _1052_grumpy_bookstore_owner {

    /**
     * 滑动窗口计算出连续X的最大值，并记录下标
     * 第一版思路不是很对
     *
     * @param customers
     * @param grumpy
     * @param x
     * @return
     */
    public int maxSatisfied_error(int[] customers, int[] grumpy, int x) {
        int sum = 0, end = x;
        for (int i = 0; i < x; i++) {
            sum += customers[i];
        }

        int currentSum;
        for (int i = x; i < customers.length; i++) {
            currentSum = sum + customers[i] - customers[i - x];
            if (currentSum > sum) {
                sum = currentSum;
                end = i;
            }
        }

        for (int i = end; i >= end - x; i--) {
            grumpy[i] = 0;
        }
        int total = 0;
        for (int i = 0; i < customers.length; i++) {
            if (grumpy[i] == 0) {
                total += customers[i];
            }
        }
        return total;
    }

    /**
     * 题解：
     * 滑动窗口找出原本生气不满意客户的最大值 + 本来就满意的客户
     *
     * @param customers
     * @param grumpy
     * @param x
     * @return
     */
    public int maxSatisfied(int[] customers, int[] grumpy, int x) {
        int sum = 0, len = customers.length;
        for (int i = 0; i < len; i++) {
            sum += customers[i] * (1 - grumpy[i]);
        }
        //滑动窗口找出生气不满意的最大值
        int grumpySum = 0;
        for (int i = 0; i < x; i++) {
            grumpySum -= customers[i] * grumpy[i];
        }

        int current = grumpySum;
        for (int i = x; i < len; i++) {
            current = current - customers[i] * grumpy[i] + customers[i - x] * grumpy[i - x];
            grumpySum = Math.min(grumpySum, current);
        }

        return sum - grumpySum;
    }

    @Test
    public void maxSatisfiedTest() {
        Assert.assertEquals(16, maxSatisfied(new int[]{1, 0, 1, 2, 1, 1, 7, 5}, new int[]{0, 1, 0, 1, 0, 1, 0, 1}, 3));
        Assert.assertEquals(17, maxSatisfied(new int[]{1, 0, 1, 2, 1, 1, 7, 5}, new int[]{1, 1, 1, 1, 0, 0, 0, 0}, 3));
    }
}
